package com.realtyreg.webview.controller;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.realtyreg.common.exception.ResourceNotFoundException;
import com.realtyreg.domain.entity.users.Profile;
import com.realtyreg.domain.entity.users.User;
import com.realtyreg.service.UserService;
import com.realtyreg.service.form.ChangePassFromProfileForm;
import com.realtyreg.service.form.NameForm;
import com.realtyreg.service.util.ImageUtil;
import com.realtyreg.service.util.SecurityUtil;
import com.realtyreg.service.validator.NameValidator;
import com.realtyreg.webview.message.MessageSaver;
import com.realtyreg.webview.message.MessageType;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Locale;

/**
 * @author Petro
 * @created 15.09.2012 19:52
 */
@Controller
@RequestMapping("/users")
public class UsersController {
    private static final Logger LOG = Logger.getLogger(UsersController.class);

    @Autowired
    private UserService userService;
    @Autowired
    private MessageSaver messageSaver;
    @Autowired
    private NameValidator nameValidator;
    @Autowired
    private PasswordEncoder passwordEncoder;

    //список пользователей
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String list(Model model) {
        model.addAttribute("users", userService.findAll());
        return "userList";
    }

    //просмотр профиля (как самим принципалом, так и другими пользователями)
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String viewProfile(@PathVariable Long id, Model model) {
        Profile profile = userService.findProfile(id);
        if (profile == null)
            throw new ResourceNotFoundException(String.format("Профиль id=%s не найден.", id));
        model.addAttribute(profile);
        return "profile";
    }

    //редактирование своего профиля GET
    @RequestMapping(params = "form", method = RequestMethod.GET)
    public String updateProfileForm(Model model, HttpServletRequest req) {
        User user = SecurityUtil.getUser();
        //1. форма изменения профиля
        Profile profile = userService.findProfile(user.getId());
        model.addAttribute(profile);
        //2. форма изменения имени
        NameForm nameForm = new NameForm(user);
        model.addAttribute(nameForm);
        //3.форма изменения пароля
        ChangePassFromProfileForm changePassFromProfileForm = new ChangePassFromProfileForm();
        model.addAttribute(changePassFromProfileForm);
        return "profileEdit";
    }

    //изменение профиля POST
    @RequestMapping(params = "form=profile", method = RequestMethod.POST)
    public String changeProfile(@Valid @ModelAttribute Profile profile, BindingResult result, @RequestParam(value = "image", required = false) MultipartFile photo, SessionStatus status, Model model, RedirectAttributes redirectAttributes, Locale locale) {
        User user = SecurityUtil.getUser();
        if (photo != null && !photo.isEmpty()) {
            String contentType = photo.getContentType();
            if (!contentType.equals("image/jpeg") && !contentType.equals("image/gif") && !contentType.equals("image/png")) {
                result.reject("profile.update.photo.incorrect.content.type");
            } else {
                try {
                    byte[] bytes = ImageUtil.resize(photo.getBytes(), ImageUtil.AVATAR_BIG_SIZE);
                    user.setPhoto(bytes);
                } catch (Exception e) {
                    result.reject("profile.update.photo.error");
                }
            }
        }

        if (result.hasErrors()) {
            //т.к. на странице 3 формы, то установим modelAttrbute остальных
            profile.setUser(user);
            NameForm nameForm = new NameForm(user);
            model.addAttribute(nameForm);
            ChangePassFromProfileForm changePassFromProfileForm = new ChangePassFromProfileForm();
            model.addAttribute(changePassFromProfileForm);
            return "profileEdit";
        }

        profile.setUser(user);
        userService.updateProfile(profile);
        if (ArrayUtils.isNotEmpty(user.getPhoto()))
            userService.save(user);
        status.setComplete();
        messageSaver.saveSessionMessage(redirectAttributes, MessageType.SUCCESS, "profile.update.success", locale);
        return "redirect:/users?form";
    }

    //изменение имени POST
    @RequestMapping(params = "form=name", method = RequestMethod.POST)
    public String changeName(@Valid @ModelAttribute NameForm nameForm, BindingResult result, SessionStatus status, Model model, RedirectAttributes redirectAttributes, Locale locale) {
        User user = SecurityUtil.getUser();
        nameForm.setRole(user.getRoles().iterator().next().toString());
        nameValidator.validate(nameForm, result);
        if (result.hasErrors()) {
            //т.к. на странице 3 формы, то установим modelAttrbute остальных
            Profile profile = userService.findProfile(user.getId());
            model.addAttribute(profile);
            ChangePassFromProfileForm changePassFromProfileForm = new ChangePassFromProfileForm();
            model.addAttribute(changePassFromProfileForm);
            return "profileEdit";
        }

        if (user.isJur()) {
            user.setName(nameForm.getName());
        }
        else {
            user.setSurName(nameForm.getSurName());
            user.setFirstName(nameForm.getFirstName());
            user.setPatrName(nameForm.getPatrName());
        }
        userService.save(user);
        status.setComplete();
        messageSaver.saveSessionMessage(redirectAttributes, MessageType.SUCCESS, "name.update.success", locale);
        return "redirect:/users?form";
    }

    //изменение пароля POST
    @RequestMapping(params = "form=password", method = RequestMethod.POST)
    public String changePassword(@Valid @ModelAttribute ChangePassFromProfileForm newPasswordForm, BindingResult result, SessionStatus status, Model model, RedirectAttributes redirectAttributes, Locale locale) {
        User user = SecurityUtil.getUser();
        if (!result.hasErrors()) {
            //если других ошибок нет, то проверяем текущий пароль
            String enteredPass = passwordEncoder.encodePassword(newPasswordForm.getCurrentPassword(), user.getEmail());
            String savedPass = user.getPassword();
            if (!savedPass.equals(enteredPass)) {
                result.reject("change.pass.incorrect.current.pass");
            }
        }
        if (result.hasErrors()) {
            //т.к. на странице 3 формы, то установим modelAttrbute остальных
            Profile profile = userService.findProfile(user.getId());
            model.addAttribute(profile);
            NameForm nameForm = new NameForm(user);
            model.addAttribute(nameForm);
            return "profileEdit";
        }

        user.setPassword(passwordEncoder.encodePassword(newPasswordForm.getPasswordForm().getNewPassword(), user.getEmail()));
        userService.save(user);
        status.setComplete();
        messageSaver.saveSessionMessage(redirectAttributes, MessageType.SUCCESS, "change.pass.success", locale);
        return "redirect:/users?form";
    }
}
